
npx create-react-app my-app --template redux
// npm
npm i react-redux @reduxjs/toolkit
// yarn
yarn add react-redux @reduxjs/toolkit
可依自己的需求安裝環境
使用 Redux Toolkit,你會聽到幾個關鍵字:
store:用來存放資料狀態reducer:用來放改變 state 狀態的方法action:reducer 要修改 state 的話,需要傳入 action ,去判斷要啟動哪個 reducer,藉由 dispatch 呼叫方法Provider:在所有組件的最外面包一層 Provider,傳入 store,所有被包覆的組件都可以使用到 store 的狀態。slice:存放 state、reducer、action 的檔案Store
Provider,並傳入 store,使整個組件都能使用 store 資料Slice,設定 state、reducer、action製作一個 todoList 列表,輸入框輸入文字,點擊按鈕後新增行程
store/index.js
import { configureStore } from "@reduxjs/toolkit";
import todoReducer from "./slice/todo";
export default configureStore({
reducer: {
todo: todoReducer,
},
});
將 slice 新增在 reducer
configureStore:創建 store 的參數,原生為 creactStore,使用 creactStore 時會有被棄用的警告
import { configureStore } from "@reduxjs/toolkit";
import todoReducer from "./slice/todo";
import productReducer from "./slice/product";
export default configureStore({
reducer: {
todo: todoReducer,
product: productReducer
},
});
如有多個檔案,一樣 import 進來,新增在 reducer
src/App.js
import { Provider } from "react-redux";
import store from "./store/index";
import Todo from "./Todo";
export default function App() {
return (
<Provider store={store}>
<Todo />
</Provider>
);
}
載入 Provider 與 store,Provider 組件傳入 store
包在 Provider 裡的組件都可以使用 store
store/slice/todo.js
import { createSlice } from "@reduxjs/toolkit";
export const todoSlice = createSlice({
name: "todo",
initialState: {
todolist: [
{ id: 1, name: "起床" },
{ id: 2, name: "刷牙洗臉" },
{ id: 3, name: "吃早餐" },
{ id: 4, name: "上班" }
]
},
reducers: {
addTodo: (state, action) => {
state.todolist.push(action.payload);
}
}
});
export const { addTodo } = todoSlice.actions; // 取用方法
export const selectTodo = (state) => state.todo; // 取用資料
export default todoSlice.reducer;
createSlice:創建 slice,把 Redux 原生的 state、reducer、action 都合在一包,稱之為 slice
name:取一個相關的名稱
initialState:所有狀態的初始值
reducers:存放函式,傳入兩個參數,第一個為需要修改的 state,第二個為 action 讓你傳入的參數,用來改變 state
components/TodoList.js
import { useSelector } from "react-redux";
import { selectTodo } from "../store/slice/todo";
const TodoList = () => {
const states = useSelector(selectTodo);
return (
<ul>
{states.todolist.map((i) => (
<li key={i.id}>{i.name}</li>
))}
</ul>
);
};
export default TodoList;
將預設行程渲染出來
useSelector:拿取 store 的 state,傳入在 slice 建立的 selectTodo
src/Todo.js
import { useDispatch } from "react-redux";
import TodoList from "./components/TodoList";
import { addTodo } from "./store/slice/todo";
import { useState } from "react";
export default function Todo() {
const [text, setText] = useState("");
const changeText = (e) => {
setText(e.target.value);
};
const dispatch = useDispatch();
const handleAddTodo = () => {
dispatch(addTodo({ id: new Date().getTime(), name: text }));
};
return (
<div>
<input
type="text"
value={text}
onChange={changeText}
/>
<TodoList />
<button onClick={handleAddTodo}>
新增行程
</button>
</div>
);
}
建立輸入框,按鈕新增行程,將 id、輸入文字傳入 addTodo
useDispatch:需藉由 useDispatch 使用 store 裡的 actions,傳入在 slice 建立的 addTodo()

打開 codesandbox 程式碼範例 一起玩看看吧!
Redux Toolkit 真的比 Redux 好懂很多,真是感謝 Redux Toolkit 的出現![]()
如果專案滿大的話,滿推薦使用 Redux Toolkit 來管理狀態資料,
學會了基本的 store 使用,明天繼續來講怎麼用 Redux Toolkit 操作非同步吧!
本文將同步更新至我的部落格
Lala 的前端大補帖